"""
S8设备控制器
S8 Device Controller

S8智能手环设备的主要控制逻辑
Main control logic for S8 smart wristband device
"""

import logging
import asyncio
from typing import Dict, Any, Optional, List
from datetime import datetime

from ..base import BaseDevice
from .protocol import S8Protocol
from .models import S8DataModels

# 导入业务逻辑处理函数 / Import business logic handler functions
from utils.logger_util import save_data_log_s8_mongo, save_data_log_s8_health_mongo

logger = logging.getLogger(__name__)


class S8Device(BaseDevice):
    """
    S8设备控制器
    S8 Device Controller
    
    负责处理S8设备的所有数据和命令
    Responsible for handling all data and commands for S8 devices
    """
    
    def __init__(self, device_id: str):
        """
        初始化S8设备
        Initialize S8 device
        
        Args:
            device_id (str): 设备唯一标识符 / Device unique identifier
        """
        super().__init__(device_id)
        self.protocol = S8Protocol()
        self.data_models = S8DataModels()
        
        # 处理函数映射表 / Handler function mapping table
        self.handler_mapping = {
            "location": self._handle_location,
            "health": self._handle_health,
            "battery": self._handle_battery,
            "sensor": self._handle_sensor,
            "alert": self._handle_alert,
            "status": self._handle_status
        }
        
        self.logger.info(f"S8设备初始化完成 / S8 device initialization completed: {device_id}")
    
    def _get_device_type(self) -> str:
        """
        获取设备类型
        Get device type
        
        Returns:
            str: 设备类型 / Device type
        """
        return "S8"
    
    def get_supported_actions(self) -> List[str]:
        """
        获取设备支持的操作类型
        Get supported action types for the device
        
        Returns:
            List[str]: 支持的操作列表 / List of supported actions
        """
        return list(self.handler_mapping.keys())
    
    async def process_data(self, raw_data: Dict[str, Any]) -> Optional[Any]:
        """
        处理原始数据
        Process raw data
        
        Args:
            raw_data (Dict[str, Any]): 原始数据 / Raw data
            
        Returns:
            Optional[Any]: 处理结果 / Processing result
        """
        try:
            # 标准化数据格式 / Normalize data format
            normalized_data = await self.protocol.normalize_device_data(raw_data)
            
            # 确定数据类型 / Determine data type
            data_type = normalized_data.get("type") or normalized_data.get("action")
            if not data_type:
                data_type = S8DataModels.infer_data_type(normalized_data)
            
            if not data_type:
                return await self.protocol.format_error_response(400, "无法确定数据类型 / Cannot determine data type")
            
            # 记录数据接收 / Log data reception
            await self.log_data_received(data_type, normalized_data)
            
            # 协议解析 / Protocol parsing
            validated_data = await self.protocol.parse_request(normalized_data)
            if not validated_data:
                return await self.protocol.format_error_response(400, "数据解析失败 / Data parsing failed")
            
            # 获取处理函数 / Get handler function
            handler = self.handler_mapping.get(data_type)
            if not handler:
                # S8设备可能有未知的数据类型，记录日志但不报错 / S8 devices may have unknown data types, log but don't error
                self.logger.warning(f"未知的S8数据类型: {data_type} / Unknown S8 data type: {data_type}")
                return await self.protocol.format_response({"msg": "数据已记录 / Data logged"})
            
            # 执行处理逻辑 / Execute processing logic
            result = await handler(validated_data)
            
            # 格式化响应 / Format response
            return await self.protocol.format_response({"flag": 1, "msg": "处理成功 / Processing successful", "obj": result or {"test": 1}})
            
        except Exception as e:
            await self.handle_error(e, f"处理S8数据时发生错误 / Error occurred while processing S8 data: {data_type}")
            return await self.protocol.format_error_response(500, f"服务器内部错误 / Internal server error: {str(e)}")
    
    async def validate_data(self, data: Dict[str, Any]) -> bool:
        """
        验证数据有效性
        Validate data integrity
        
        Args:
            data (Dict[str, Any]): 待验证数据 / Data to validate
            
        Returns:
            bool: 验证结果 / Validation result
        """
        return await self.protocol.validate_request(data)
    
    async def send_command(self, command: Dict[str, Any]) -> Dict[str, Any]:
        """
        向设备发送命令
        Send command to device
        
        Args:
            command (Dict[str, Any]): 命令数据 / Command data
            
        Returns:
            Dict[str, Any]: 命令执行结果 / Command execution result
        """
        try:
            # S8设备命令发送逻辑（待实现）/ S8 device command sending logic (to be implemented)
            self.logger.info(f"S8设备命令发送（待实现）/ S8 device command sending (to be implemented): {self.device_id}")
            
            # 暂时返回成功响应 / Return success response temporarily
            return {
                "flag": 1,
                "msg": "S8命令发送功能待实现 / S8 command sending feature to be implemented",
                "obj": {"command": command}
            }
            
        except Exception as e:
            await self.handle_error(e, "发送S8命令时发生错误 / Error occurred while sending S8 command")
            return {"flag": 0, "msg": f"命令发送失败 / Command sending failed: {str(e)}"}
    
    # 私有处理方法 / Private handler methods
    
    async def _handle_location(self, data) -> Any:
        """
        处理定位数据
        Handle location data
        
        Args:
            data: 定位数据模型 / Location data model
            
        Returns:
            Any: 处理结果 / Processing result
        """
        try:
            self.logger.info(f"处理S8定位数据 / Processing S8 location data: {self.device_id}")
            
            # 安全地保存到MongoDB / Safely save to MongoDB
            try:
                data_dict = data.dict() if hasattr(data, 'dict') else (data if isinstance(data, dict) else {})
                
                # 添加超时控制的MongoDB操作 / Add timeout control for MongoDB operation
                await asyncio.wait_for(
                    save_data_log_s8_mongo(data_dict),
                    timeout=10.0
                )
            except asyncio.TimeoutError:
                self.logger.error(f"S8定位数据保存超时 / S8 location data save timeout: {self.device_id}")
                # 继续处理，不让数据库错误阻断业务逻辑 / Continue processing, don't let DB errors block business logic
            except Exception as db_error:
                self.logger.error(f"保存S8定位数据到MongoDB失败 / Failed to save S8 location data to MongoDB: {str(db_error)}")
                # 继续处理 / Continue processing
            
            # 安全地更新位置元数据 / Safely update location metadata
            try:
                longitude = getattr(data, 'longitude', None)
                latitude = getattr(data, 'latitude', None)
                
                if longitude is not None and latitude is not None:
                    location_metadata = {
                        "longitude": float(longitude),
                        "latitude": float(latitude),
                        "accuracy": getattr(data, 'accuracy', None),
                        "timestamp": getattr(data, 'timestamp', None),
                        "updated_at": datetime.now().isoformat()
                    }
                    
                    # 移除None值 / Remove None values
                    location_metadata = {k: v for k, v in location_metadata.items() if v is not None}
                    
                    self.update_metadata("last_location", location_metadata)
                    
            except Exception as meta_error:
                self.logger.warning(f"更新S8位置元数据失败 / Failed to update S8 location metadata: {str(meta_error)}")
            
            return {"processed": True, "type": "location", "device_id": self.device_id}
            
        except Exception as e:
            self.logger.error(f"处理S8定位数据失败 / S8 location data processing failed: {str(e)}")
            # 不直接抛出异常，返回错误信息 / Don't throw exception directly, return error info
            return {"processed": False, "type": "location", "error": str(e), "device_id": self.device_id}
    
    async def _handle_health(self, data) -> Any:
        """
        处理健康数据
        Handle health data
        
        Args:
            data: 健康数据模型 / Health data model
            
        Returns:
            Any: 处理结果 / Processing result
        """
        try:
            self.logger.info(f"处理S8健康数据 / Processing S8 health data: {self.device_id}")
            
            # 安全地保存到MongoDB / Safely save to MongoDB
            try:
                data_dict = data.dict() if hasattr(data, 'dict') else (data if isinstance(data, dict) else {})
                
                # 添加超时控制的MongoDB操作 / Add timeout control for MongoDB operation
                await asyncio.wait_for(
                    save_data_log_s8_health_mongo(data_dict),
                    timeout=10.0
                )
            except asyncio.TimeoutError:
                self.logger.error(f"S8健康数据保存超时 / S8 health data save timeout: {self.device_id}")
            except Exception as db_error:
                self.logger.error(f"保存S8健康数据到MongoDB失败 / Failed to save S8 health data to MongoDB: {str(db_error)}")
            
            # 安全地更新健康状态元数据 / Safely update health status metadata
            try:
                health_metadata = {
                    "timestamp": getattr(data, 'timestamp', None),
                    "updated_at": datetime.now().isoformat()
                }
                
                # 收集所有有效的健康指标 / Collect all valid health indicators
                health_fields = ['heart_rate', 'blood_oxygen', 'body_temperature', 'blood_pressure', 'steps']
                for field in health_fields:
                    value = getattr(data, field, None)
                    if value is not None and value != 0 and value != "":
                        health_metadata[field] = value
                
                if len(health_metadata) > 2:  # 除了timestamp和updated_at还有其他数据
                    self.update_metadata("last_health", health_metadata)
                    
                    # 统计健康数据收集次数 / Count health data collection occurrences
                    health_count = self.get_metadata("health_count") or 0
                    self.update_metadata("health_count", health_count + 1)
                    
            except Exception as meta_error:
                self.logger.warning(f"更新S8健康元数据失败 / Failed to update S8 health metadata: {str(meta_error)}")
            
            return {"processed": True, "type": "health", "device_id": self.device_id}
            
        except Exception as e:
            self.logger.error(f"处理S8健康数据失败 / S8 health data processing failed: {str(e)}")
            return {"processed": False, "type": "health", "error": str(e), "device_id": self.device_id}
    
    async def _handle_battery(self, data) -> Any:
        """
        处理电池数据
        Handle battery data
        
        Args:
            data: 电池数据模型 / Battery data model
            
        Returns:
            Any: 处理结果 / Processing result
        """
        try:
            self.logger.info(f"处理S8电池数据 / Processing S8 battery data: {self.device_id}")
            
            # 安全地更新电池状态元数据 / Safely update battery status metadata
            try:
                battery_metadata = {
                    "timestamp": getattr(data, 'timestamp', None),
                    "updated_at": datetime.now().isoformat()
                }
                
                # 收集电池相关信息 / Collect battery related information
                battery_level = getattr(data, 'battery_level', None)
                charging_status = getattr(data, 'charging_status', None)
                power_mode = getattr(data, 'power_mode', None)
                
                if battery_level is not None:
                    battery_metadata['battery_level'] = battery_level
                    # 保持向后兼容 / Maintain backward compatibility
                    self.update_metadata("battery_level", battery_level)
                    
                if charging_status is not None:
                    battery_metadata['charging_status'] = charging_status
                    self.update_metadata("charging_status", charging_status)
                    
                if power_mode is not None:
                    battery_metadata['power_mode'] = power_mode
                
                if len(battery_metadata) > 2:  # 除了timestamp和updated_at还有其他数据
                    self.update_metadata("battery_info", battery_metadata)
                    
            except Exception as meta_error:
                self.logger.warning(f"更新S8电池元数据失败 / Failed to update S8 battery metadata: {str(meta_error)}")
            
            return {"processed": True, "type": "battery", "device_id": self.device_id}
            
        except Exception as e:
            self.logger.error(f"处理S8电池数据失败 / S8 battery data processing failed: {str(e)}")
            return {"processed": False, "type": "battery", "error": str(e), "device_id": self.device_id}
    
    async def _handle_sensor(self, data) -> Any:
        """
        处理传感器数据
        Handle sensor data
        
        Args:
            data: 传感器数据模型 / Sensor data model
            
        Returns:
            Any: 处理结果 / Processing result
        """
        try:
            self.logger.info(f"处理S8传感器数据 / Processing S8 sensor data: {self.device_id}")
            
            # 安全地更新传感器数据元数据 / Safely update sensor data metadata
            try:
                sensor_metadata = {
                    "timestamp": getattr(data, 'timestamp', None),
                    "updated_at": datetime.now().isoformat()
                }
                
                # 收集传感器数据 / Collect sensor data
                sensor_fields = ['accelerometer', 'gyroscope', 'magnetometer', 'ambient_light', 'pressure']
                for field in sensor_fields:
                    value = getattr(data, field, None)
                    if value is not None:
                        sensor_metadata[field] = value
                
                if len(sensor_metadata) > 2:  # 除了timestamp和updated_at还有其他数据
                    self.update_metadata("last_sensor", sensor_metadata)
                    
                    # 统计传感器数据收集次数 / Count sensor data collection occurrences
                    sensor_count = self.get_metadata("sensor_count") or 0
                    self.update_metadata("sensor_count", sensor_count + 1)
                    
            except Exception as meta_error:
                self.logger.warning(f"更新S8传感器元数据失败 / Failed to update S8 sensor metadata: {str(meta_error)}")
            
            return {"processed": True, "type": "sensor", "device_id": self.device_id}
            
        except Exception as e:
            self.logger.error(f"处理S8传感器数据失败 / S8 sensor data processing failed: {str(e)}")
            return {"processed": False, "type": "sensor", "error": str(e), "device_id": self.device_id}
    
    async def _handle_alert(self, data) -> Any:
        """
        处理警报数据
        Handle alert data
        
        Args:
            data: 警报数据模型 / Alert data model
            
        Returns:
            Any: 处理结果 / Processing result
        """
        try:
            alert_type = getattr(data, 'alert_type', 'unknown')
            alert_level = getattr(data, 'alert_level', 1)
            
            self.logger.info(
                f"处理S8警报数据 / Processing S8 alert data: {self.device_id}, "
                f"类型 / Type: {alert_type}, 级别 / Level: {alert_level}"
            )
            
            # 安全地更新警报状态元数据 / Safely update alert status metadata
            try:
                alert_metadata = {
                    "alert_type": alert_type,
                    "alert_level": alert_level,
                    "timestamp": getattr(data, 'timestamp', None),
                    "processed_at": datetime.now().isoformat()
                }
                
                # 收集警报相关信息 / Collect alert related information
                alert_message = getattr(data, 'alert_message', None)
                location = getattr(data, 'location', None)
                
                if alert_message:
                    alert_metadata['alert_message'] = alert_message
                if location:
                    alert_metadata['location'] = location
                
                self.update_metadata("last_alert", alert_metadata)
                
                # 统计警报次数 / Count alert occurrences
                alert_count = self.get_metadata("alert_count") or 0
                self.update_metadata("alert_count", alert_count + 1)
                
                # 按级别统计警报 / Count alerts by level
                level_key = f"alert_level_{alert_level}_count"
                level_count = self.get_metadata(level_key) or 0
                self.update_metadata(level_key, level_count + 1)
                
            except Exception as meta_error:
                self.logger.warning(f"更新S8警报元数据失败 / Failed to update S8 alert metadata: {str(meta_error)}")
            
            return {"processed": True, "type": "alert", "device_id": self.device_id, "alert_type": alert_type}
            
        except Exception as e:
            self.logger.error(f"处理S8警报数据失败 / S8 alert data processing failed: {str(e)}")
            return {"processed": False, "type": "alert", "error": str(e), "device_id": self.device_id}
    
    async def _handle_status(self, data) -> Any:
        """
        处理状态数据
        Handle status data
        
        Args:
            data: 状态数据模型 / Status data model
            
        Returns:
            Any: 处理结果 / Processing result
        """
        try:
            self.logger.info(f"处理S8状态数据 / Processing S8 status data: {self.device_id}")
            
            # 安全地更新设备状态元数据 / Safely update device status metadata
            try:
                status_metadata = {
                    "timestamp": getattr(data, 'timestamp', None),
                    "updated_at": datetime.now().isoformat()
                }
                
                # 收集设备状态相关信息 / Collect device status related information
                status_fields = [
                    'firmware_version', 'hardware_version', 'connection_status',
                    'last_sync_time', 'memory_usage'
                ]
                
                for field in status_fields:
                    value = getattr(data, field, None)
                    if value is not None and value != "":
                        status_metadata[field] = value
                
                if len(status_metadata) > 2:  # 除了timestamp和updated_at还有其他数据
                    self.update_metadata("device_status", status_metadata)
                    
                    # 统计状态更新次数 / Count status update occurrences
                    status_count = self.get_metadata("status_update_count") or 0
                    self.update_metadata("status_update_count", status_count + 1)
                    
            except Exception as meta_error:
                self.logger.warning(f"更新S8状态元数据失败 / Failed to update S8 status metadata: {str(meta_error)}")
            
            return {"processed": True, "type": "status", "device_id": self.device_id}
            
        except Exception as e:
            self.logger.error(f"处理S8状态数据失败 / S8 status data processing failed: {str(e)}")
            return {"processed": False, "type": "status", "error": str(e), "device_id": self.device_id}